package com.yst.webplugin.component;



import com.yst.spring.context.SpringContext;
import com.yst.webplugin.annotation.HttpInfo;
import com.yst.webplugin.api.Api;
import com.yst.webplugin.fieldhandler.FieldHandler;
import com.yst.webplugin.log.ILogger;
import com.yst.webplugin.loginplugin.UserUtils;
import com.yst.webplugin.permission.PermissionUtils;
import com.yst.webplugin.util.IPUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;


@Component
public class CRUDInterceptor implements HandlerInterceptor {

    private Map<String,Object> makeHeaders(HttpServletRequest request){
        Map<String,Object> headers=new HashMap<>();
        for(String key: Collections.list(request.getHeaderNames())){
            headers.put(key,request.getHeader(key));
        }
        return headers;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {

        ILogger logger=null;
        try {
            logger=SpringContext.getContext().getBean(ILogger.class);
        }
        catch (Exception ignore){

        }

        Api.ApiMethod log=null;

        try {

            if (handler instanceof HandlerMethod) {
                UserUtils.checkLogin(((HandlerMethod) handler).getMethod());
                PermissionUtils.checkPermission(((HandlerMethod) handler).getMethod());
                log=(((HandlerMethod)handler).getMethod()).getAnnotation(Api.ApiMethod.class);
            }

            if (handler instanceof FieldHandler) {
                ControllerUtil.checkResultType(((FieldHandler) handler).getField());
                UserUtils.checkLogin(((FieldHandler) handler).getField());
                PermissionUtils.checkPermission(((FieldHandler) handler).getField());
                log=(((FieldHandler)handler).getField()).getAnnotation(Api.ApiMethod.class);
            }

            if (Objects.nonNull(log)&&Objects.nonNull(logger)&&log.recordLog()){
                logger.writeSuccessLog(request.getRequestURI(), IPUtils.getRealIp(request), log.value(),
                        makeHeaders(request));
            }

        }
        catch (Exception e){
            HttpInfo httpInfo=new HttpInfo(request,response);
            httpInfo.writeThrowable(e);

            if (Objects.nonNull(log)&&Objects.nonNull(logger)&&log.recordLog()){
                logger.writeFailLog(request.getRequestURI(), IPUtils.getRealIp(request), log.value(),
                        makeHeaders(request));
            }
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}
